#![allow(non_snake_case)]
mod chart_report;
mod list_report;
mod report_header;
mod sub_report;
use crate::{components::{loading::Loading, server_error::ServerError}, report::chart_report::ChartReport};
use leptos::prelude::*;
use list_report::ListReport;
use shq_common::prelude::{report::ReportDefine, AuthType};
#[component]
pub fn Report(
    menu_id: u32,
    #[prop(into)] rept_name: Oco<'static, str>,
    #[prop(optional, into)] title: MaybeProp<String>,
    #[prop(optional, into)] params: MaybeProp<Vec<(String, String)>>,
    #[prop(optional, into)] extra_where: MaybeProp<String>,
) -> impl IntoView {
    let rept_name = StoredValue::new(rept_name.to_string());
    let rept_conf = Resource::new(
        move || (rept_name.get_value(), params.get().unwrap_or_default()),
        move |(rept_name, params)| async move {
            let jval_res = get_rept_define(menu_id, rept_name, params).await;
            jval_res
        },
    );
    view! {
        <Suspense fallback=|| view! { <Loading/> }>
            {move || match rept_conf.get() {
                None => view! { <p>"Loading..."</p> }.into_any(),
                Some(mv_res) => match mv_res {
                    Ok(rd) => {
                        let rept_define = Signal::derive(move||rd.clone());
                        if rept_define.with(|rd| rd.chart.is_some()) {
                            view! {<ChartReport menu_id rept_name rept_define title params extra_where/>}.into_any()
                        }else{
                            view! {<ListReport menu_id rept_name rept_define title params extra_where/>}.into_any()
                        }
                    }
                    Err(err) => view! { <ServerError err_msg=err.to_string().into()/> }.into_any(),
                },
            }}
        </Suspense>
    }
}

#[server(GetReptConfig, "/api/protect")]
pub async fn get_rept_define(
    menu_id: u32,
    conf_name: String,
    #[server(default)] params: Vec<(String, String)>,
) -> Result<ReportDefine, ServerFnError> {
    use crate::auth::get_user_context_with_auth;
    let user = get_user_context_with_auth(menu_id, AuthType::Select).await?;
    let params: Vec<(&str, &str)> = params
        .iter()
        .map(|(k, v)| (k.as_str(), v.as_str()))
        .collect();
    let rept = shq_report::ReportService::new(&conf_name, &params, user.user_id, menu_id).await?;
    let result = rept.get_rept_define().await;
    match result {
        Ok(conf) => {
            Ok(conf)
        },
        Err(e) => {
            let err_msg = format!("get_rept_define error:{}", e);
            Err(ServerFnError::ServerError(err_msg))
        }
    }
}
